#include <iostream>
#include <fstream>

#include "Compresor"

/**
Programa de prueba para Compresor archivo: "cacararamememama"
Simula comportamiento de Modelo Estructurado
	//Comprimiendo archivo que contiene texto: "cacarara"
	//Salida blocksorting: rcrcaaaa
	//Salida MTF:114,100,1,1,99,0,0,0
*/


using namespace std;

int main() {
	ofstream archivo("salidaCompAritm.txt");
	obitstream bitwiseFile(&archivo);
	Compresor ejem(&bitwiseFile);

	cout<<"Techo por defecto: "<<ejem.techo()<<endl;
	cout<<"Piso por defecto: "<<ejem.piso()<<endl;
	/**comprime 114*/
	ejem.proximo(1,1,2);//Escape en nivel 0 - Emite bits: underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(1,1,2);//Escape en nivel 1 - Emite bits:1 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(2,1,3);//Escape en nivel 2 - Emite bits:11 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(4,1,5);//Escape en nivel 3 - Emite bits:11 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(8,1,9);//Escape en nivel 4 - Emite bits:1111 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(16,1,17);//Escape en nivel 5 - Emite bits:1111 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(32,1,33);//Escape en nivel 6 - Emite bits:11111 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(50,1,65);//Emite 114 en nivel 7 - Emite bits:110 underflow:+2 contUnder acumulado:2
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	/**comprime 100*/
	ejem.proximo(1,2,3);//Escape en nivel 0 - Emite bits: underflow:+0 contUnder acumulado:2
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(1,2,3);//Escape en nivel 1 - Emite bits: underflow:+1 contUnder acumulado:3
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(2,2,4);//Escape en nivel 2 - Emite bits: underflow:+1 contUnder acumulado:4
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(4,2,6);//Escape en nivel 3 - Emite bits: underflow:+2 contUnder acumulado:6
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(8,2,10);//Escape en nivel 4 - Emite bits:100000010 underflow:--6 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(16,2,18);//Escape en nivel 5 - Emite bits:11 underflow:+1 contUnder acumulado:1
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(32,2,34);//Escape en nivel 6 - Emite bits:10111 underflow:--1 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(36,1,66);//Emite 100 en nivel 7 - Emite bits:101100 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	/**comprime 1*/
	ejem.proximo(1,3,4);//Escape en nivel 0 - Emite bits: underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(0,1,4);//Emite 1 en nivel 1 - Emite bits: underflow:+2 contUnder acumulado:2
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	/**comprime 1 */
	ejem.proximo(1,4,5); //Escape en nivel 0 - Emite bits: underflow:+1 contUnder acumulado:3
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(0,2,5); //Emite 1 en nivel 1 - Emite bits:0111 underflow:--3 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	/**comprime 99*/
	ejem.proximo(1,5,6); //Escape en nivel 0 - Emite bits: underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(3,3,6); //Escape en nivel 1 - Emite bits: underflow:+1 contUnder acumulado:1
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(2,3,5); //Escape en nivel 2 - Emite bits:10 underflow:--1 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(4,3,7); //Escape en nivel 3 - Emite bits:1 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(8,3,11); //Escape en nivel 4 - Emite bits:11 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(16,3,19); //Escape en nivel 5 - Emite bits:1 underflow:+1 contUnder acumulado:1
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(32,3,35); //Escape en nivel 6 - Emite bits:10001 underflow:--1 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(35,1,67); //Emite 99 en nivel 7 - Emite bits:011100 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	/**comprime 0 */
	ejem.proximo(0,1,7); //Emite 0 en nivel 0 - Emite bits:01 underflow:+1 contUnder acumulado:1
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	/**comprime 0 */
	ejem.proximo(0,2,8); //Emite 0 en nivel 0 - Emite bits:010 underflow:--1 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	/**comprime 0 */
	ejem.proximo(0,3,9); //Emite 0 en nivel 0 - Emite bits:00 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	/**comprime EOF */
	/** Investigacion subsiguiente: trato de reemplazar estos bits emitidos x EOF x una cte fija, notar que para este caso se emitieron 24 bits de EOF + 2 bits + 7 de relleno
	la idea es que el compresor aritmetico sea instanciado con la cte BUFF_SIZE, ya que el problema es la descompresion
	va a descomprimir hasta BUFF_SIZE caracteres y se detiene, o se le termina el archivo origen de la descompresion, en ese
	caso hay que mantener doble bitbuffer y procesar de manera retardada..I don't now yet*/
	ejem.proximo(4,6,10); //Escape en nivel 0 - Emite bits: underflow:+1 contUnder acumulado:1
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(3,4,7); //Escape en nivel 1 - Emite bits: underflow:+0 contUnder acumulado:1
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(2,4,6); //Escape en nivel 2 - Emite bits:10 underflow:--1 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(4,4,8); //Escape en nivel 3 - Emite bits:1 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(8,4,12); //Escape en nivel 4 - Emite bits:11 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(16,4,20); //Escape en nivel 5 - Emite bits:11 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(32,4,36); //Escape en nivel 6 - Emite bits:1 underflow:+2 contUnder acumulado:2
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(67,1,68); //Escape en nivel 7 - Emite bits:10011111 underflow:--2 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.proximo(128,1,129); //Emite EOF en nivel 8 - Emite bits:1111111 underflow:+0 contUnder acumulado:0
	cout<<"Techo: "<<ejem.techo()<<" Piso: "<<ejem.piso()<<endl;
	ejem.finalizar(); // - Emite bits:01
	bitwiseFile.pad();
	archivo.close();
/*
11111111 11111111 11110100 00001011 | FF FF F4 0B
10111101 10001111 01111100 01011100 | BD 8F 7C 5C
01010001 01111111 00111111 11111101 | 51 7F 3F FD
*/
	return 0;
}

